#include <SDL/SDL.h>
#include "zone.h"
#include "video.h"
#include "draw.h"
#include <stdio.h>
bool ran=false;

word old256;
extern byte *v_16x16;
extern byte *v_256x256;
extern byte *v_lvllayout;



#define debug_tiles
word flipx,flipy;

char newText[100];

void printbits(word n) 
{
    unsigned int i;
    i = 1 << (sizeof(n) * 8 - 1);

    while (i > 0) {
        if (n & i)
		    printf("1");
		else
			printf("0");
		i >>= 1;
	}
}

void LoadTilesFromStart(int screenx, int screeny)
{
    #ifdef debug_tiles
    printf("LoadTilesFromStart:\n");
    printf("\nLevel Layout: \n");
    printf("\n\nNow calling DrawChunks...\n");
    #endif
    
    //screeny=screeny+752;
	DrawChunks(screenx, screeny, 16384, 0);
	//screeny=screeny-752;
	
	//#define SONIC_REVISION 0
    //#if SONIC_REVISION==0
    //screeny=screeny+16;
    DrawChunks(0, 0, 24576, 0x40); /*a3=$FFFFF708*, bglayout);*/
    //screeny=screeny-16;
	//#else
	
	//different bg drawing functions
	//#endif
    
	//additional work for zones here
}

void DrawChunks(int screenx, int screeny, int num, word layoutIndex)
{
    signed int d4=0;  //-16; //offset to add to y when calculating
	int d5=0;  //offset to add to x when calculating
	int d6=15;
	signed int d1=d4;
	
	#ifdef debug_tiles
    //printf("calcVramPos(screenx=%i, screeny=%i, d4=%i, d5=%i)=", screenx, screeny, d4, d5);
    #endif
    long d0=calcVramPos(screenx, screeny, d4, d5);     //calc vram pos returns an offset index into fgram based on screenx, screeny (in rom this uses d4 and d5)
	#ifdef debug_tiles
    //printf("%i\n", d0);
	#endif
	
	//int count1=count1old;
	d4=d1;
	d5=0;
	
	//d6=31 times left to right to cover all of foreground ram in the x direction including the 256's that arent entirely on-screen if any
    d6=31;
    
    for (int oldd6=0; oldd6<=15; oldd6++)
    {
       
       d0=calcVramPos(screenx, screeny, d4, d5);     //calc vram pos returns an offset index into fgram based on screenx, screeny added with d4 and d5 to iterate

       
       DrawTiles_LR_2(screenx, screeny, d0, d4, d5, d6, num, layoutIndex);  //d0=offset based on screen, d4=current tile y, d5=current tile x, d6=number of times left to right  
       d4=d4+16; 
    }
    
    word *fgRam=getfgRam();
    #ifdef debug_tiles
    for (int y=0; y<64; y++)
     {
         for (int x=0; x<64; x++)
         {
             //printf("%04X ", fgRam[(x+(y*64))]);
         }
         //printf("\n");
     }
     #endif
    //ran=true;
    //}
}


long calcVramPos(int screenx, int screeny, int val1, int val2)//accounts for offset into 256 tile to grab 16x16 based on screen position
{
     

    
    val1=val1+screeny;
	val2=val2+screenx;
	val1&=0xF0; //round to nearest multiple of 16, screen.y in terms of 16x16s < 255
	val2&=0x1F0;//round to nearest multiple of 16, screen.x in terms of 16x16s < 512
	
    //val1=val1*16; //bytes per line
	//val2=val2/4;  //bytes per x value
	val1=(val1/16)*128;
	val2=(val2/16);
    
    //return 0x30000+val1+val2;
    //^genesis calculations, we are concerned with returning an index here
    
    return val1+val2;
}

void DrawTiles_LR_2(int screenx, int screeny, int tileIndex, long v1, long v2, long v3, int num, word layoutIndex)
{
     
    int TLENGTH=64;
	long d7 = 0x800000;      //value to add for vdp write
	long d1 = tileIndex;     //offset into fgram based on screen location since this is used by drawblocks
                             //calculated by calcvrampos
                             //used to cover screen with all adjacent 256s
	for (int times=0; times <= v3; times++)
	{
        #ifdef debug_tiles
        //printf ("d1(%i)=tileIndex(%i)\n", d1, tileIndex);
        #endif
        
    	//vram originaaly holds location of 8x8, in drawblocks it gets index in level layout of current 256x256
    	
        //v1=value used to iterate the drawing position y-wise    
            
        //drawblocks calulates position of current 16x16 in 256x256 mapping with offset(d1) based on screen location, 
        //to load data at position beginning with 16x16s that are to be displayed
        //
        word xflip=0, yflip=0;
        word *a1=DrawBlocks(screenx, screeny, d1, v1, v2, v3, layoutIndex);
   
        //if (a1==0) { }
    	
    	//int calc=d1/16;       //tile index 
    	//int calc2=v1;
    	
        //j1++;
        //if (j1==16){j1=0; d1=d1+32; } //skip the second set of 16x16s
        //int cur16=d1%16;
    	
        //vram = d1;          //grab original location passed to DrawTiles_LR_2
        DrawTiles(screenx, screeny, d1, num, a1);
     
    	d1 = d1 + 2;        //increment position in vram, this is 4 in rom in this case we are incrementing a 16x16 
    	//d1 = d1 & 0x7F;     //first 7 bits
    	
    	v2=v2+16;  //16 pixels over x-direction
	}
	
}

void DrawTiles(int screenx, int screeny, int tile, int num, word *v_16x16)
{
     
    //tile is the index in which to place the tiles drawn for this 16x16
	//tile = (word)tile | (word)(num-0x4000);   //d2 is passed in DrawChunks, this is what is added to vram for placement of tiles in either fg (0x4000) or bg (0x6000)
	
	
	//tile = tile * 65536;  //swap function in rom
	
	//btst	#4,(a0)
	//	bne.s	DrawFlipY
	//	btst	#3,(a0)
	//	bne.s	DrawFlipX

	int TLENGTH=64;
	int THEIGHT=64;
	
    //--then write the 4 individual 8x8s given by the 16x16 from DrawBlocks position in vram--/
    //printf("DrawTile(tile=%i, v_16x16[0]=%i)\n", tile, (v_16x16[0]&0x7FF)/0x10);
    //int index=(index256*256)+cur16x+(cur16y*16);
    
    if (flipx==1 && flipy!=1) { 
       word cur16val=((v_16x16[0]&0x00FF)<<8)+((v_16x16[0]&0xFF00)>>8);
                  
       cur16val=(cur16val ^ (1<<11));
       //cur16val=(cur16val ^ (flipy<<12));

       //word cur16val=((v_16x16[index*4]&0x00FF)<<8)
        if (num==0x4000)
           DrawTileFG(screenx, screeny, tile+1, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
           DrawTileBG(screenx, screeny, tile+1, cur16val);
           
        cur16val=((v_16x16[1]&0x00FF)<<8)+((v_16x16[1]&0xFF00)>>8);
        cur16val=(cur16val ^ (1<<11));
        //cur16val=(cur16val ^ (flipy<<12));
        
        if (num==0x4000)
           DrawTileFG(screenx, screeny, tile, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
           DrawTileBG(screenx, screeny, tile, cur16val);
        
        
        cur16val=((v_16x16[2]&0x00FF)<<8)+((v_16x16[2]&0xFF00)>>8);
        cur16val=(cur16val ^ (1<<11));
        //cur16val=(cur16val ^ (flipy<<12));
        
        if (num==0x4000)
           DrawTileFG(screenx, screeny, tile+65, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
           DrawTileBG(screenx, screeny, tile+65, cur16val);
        
        cur16val=((v_16x16[3]&0x00FF)<<8)+((v_16x16[3]&0xFF00)>>8);
        cur16val=(cur16val ^ (1<<11));
        //cur16val=(cur16val ^ (flipy<<12));
      
        if (num==0x4000)
           DrawTileFG(screenx, screeny, tile+64, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
           DrawTileBG(screenx, screeny, tile+64, cur16val);
      }
      else if (flipy==1&&flipx!=1)
      {
        word cur16val=((v_16x16[0]&0x00FF)<<8)+((v_16x16[0]&0xFF00)>>8);
              //cur16val=(cur16val ^ (flipx<<11));
        cur16val=(cur16val ^ (1<<12));
    
        if (num==0x4000)
           DrawTileFG(screenx, screeny, tile+64, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
           DrawTileBG(screenx, screeny, tile+64, cur16val);
           
        cur16val=((v_16x16[1]&0x00FF)<<8)+((v_16x16[1]&0xFF00)>>8);
        //cur16val=(cur16val ^ (flipx<<11));
        cur16val=(cur16val ^ (1<<12));
        
        if (num==0x4000)
           DrawTileFG(screenx, screeny, tile+65, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
           DrawTileBG(screenx, screeny, tile+65, cur16val);
        
        
        cur16val=((v_16x16[2]&0x00FF)<<8)+((v_16x16[2]&0xFF00)>>8);
        //cur16val=(cur16val ^ (flipx<<11));
        cur16val=(cur16val ^ (1<<12));
        
        if (num==0x4000)
           DrawTileFG(screenx, screeny, tile, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
           DrawTileBG(screenx, screeny, tile, cur16val);
        
        cur16val=((v_16x16[3]&0x00FF)<<8)+((v_16x16[3]&0xFF00)>>8);
        //cur16val=(cur16val ^ (flipx<<11));
        cur16val=(cur16val ^ (1<<12));
      
        if (num==0x4000)
           DrawTileFG(screenx, screeny, tile+1, cur16val); //vram offset divided by 0x20
        else if (num==0x6000)
           DrawTileBG(screenx, screeny, tile+1, cur16val);
        }
        else if (flipx ==1 && flipy ==1)
        {
             
            word cur16val=((v_16x16[0]&0x00FF)<<8)+((v_16x16[0]&0xFF00)>>8);
            cur16val=(cur16val ^ (1<<11));
            cur16val=(cur16val ^ (1<<12));
        
           
            if (num==0x4000)
               DrawTileFG(screenx, screeny, tile+65, cur16val); //vram offset divided by 0x20
            else if (num==0x6000)
               DrawTileBG(screenx, screeny, tile+65, cur16val);
               
            cur16val=((v_16x16[1]&0x00FF)<<8)+((v_16x16[1]&0xFF00)>>8);
            //if (cur16val)
            //{
            cur16val=(cur16val ^ (1<<11));
            cur16val=(cur16val ^ (1<<12));
            //}
            if (num==0x4000)
               DrawTileFG(screenx, screeny, tile+64, cur16val); //vram offset divided by 0x20
            else if (num==0x6000)
               DrawTileBG(screenx, screeny, tile+64, cur16val);
            
            
            cur16val=((v_16x16[2]&0x00FF)<<8)+((v_16x16[2]&0xFF00)>>8);
            cur16val=(cur16val ^ (1<<11));
            cur16val=(cur16val ^ (1<<12));
            
            if (num==0x4000)
               DrawTileFG(screenx, screeny, tile+1, cur16val); //vram offset divided by 0x20
            else if (num==0x6000)
               DrawTileBG(screenx, screeny, tile+1, cur16val);
            
            cur16val=((v_16x16[3]&0x00FF)<<8)+((v_16x16[3]&0xFF00)>>8);
            cur16val=(cur16val ^ (1<<11));
            cur16val=(cur16val ^ (1<<12));
          
            if (num==0x4000)
               DrawTileFG(screenx, screeny, tile, cur16val); //vram offset divided by 0x20
            else if (num==0x6000)
               DrawTileBG(screenx, screeny, tile, cur16val);
      }
      
      if (flipx!=1 && flipy!=1)
      {   
            word cur16val=((v_16x16[0]&0x00FF)<<8)+((v_16x16[0]&0xFF00)>>8);
           //cur16val=(cur16val ^ (flipx<<11));
           //cur16val=(cur16val ^ (flipy<<12));
        
           
            if (num==0x4000)
               DrawTileFG(screenx, screeny, tile, cur16val); //vram offset divided by 0x20
            else if (num==0x6000)
               DrawTileBG(screenx, screeny, tile, cur16val);
               
            cur16val=((v_16x16[1]&0x00FF)<<8)+((v_16x16[1]&0xFF00)>>8);
            //cur16val=(cur16val ^ (flipx<<11));
            //cur16val=(cur16val ^ (flipy<<12));
            
            if (num==0x4000)
               DrawTileFG(screenx, screeny, tile+1, cur16val); //vram offset divided by 0x20
            else if (num==0x6000)
               DrawTileBG(screenx, screeny, tile+1, cur16val);
            
            
            cur16val=((v_16x16[2]&0x00FF)<<8)+((v_16x16[2]&0xFF00)>>8);
            //cur16val=(cur16val ^ (flipx<<11));
            //cur16val=(cur16val ^ (flipy<<12));
            
            if (num==0x4000)
               DrawTileFG(screenx, screeny, tile+64, cur16val); //vram offset divided by 0x20
            else if (num==0x6000)
               DrawTileBG(screenx, screeny, tile+64, cur16val);
            
            cur16val=((v_16x16[3]&0x00FF)<<8)+((v_16x16[3]&0xFF00)>>8);
            //cur16val=(cur16val ^ (flipx<<11));
            //cur16val=(cur16val ^ (flipy<<12));
          
            if (num==0x4000)
               DrawTileFG(screenx, screeny, tile+65, cur16val); //vram offset divided by 0x20
            else if (num==0x6000)
               DrawTileBG(screenx, screeny, tile+65, cur16val);
           }    
           
}           

void DrawTileFG(int screenx, int screeny, int index, word tile)
{
     #ifdef debug_tiles
     //printf("DrawTile(tile=%i, index=%i)\n", tile, index);
     #endif
     
     fgTile(screenx,screeny,index,tile);

}

void DrawTileBG(int screenx, int screeny, int index, word tile)
{
     bgTile(screenx,screeny,index,tile);
}


word *DrawBlocks(int screenx, int screeny, int tileIndex, long v1, long v2, long v3, word layoutIndex)     //screen pos offset by v1 (x) and v2 (y) used to locate position of 16x16 mapping referred to by upper left most screen pos
{
   
    //printf("DrawBlocks(screenx = %i, screeny = %i, tileIndex = %i, v1 = %i, v2 = %i, v3 = %i, layoutIndex = %i)\n",screenx,screeny,tileIndex,v1,v2,v3,layoutIndex);
    
    v1=v1+screeny;     //calculated a second time to find 
    v2=v2+screenx;    
    
    //word *a1=(word*)currentZone.v_16x16;  
      
    //printf("1) v1 & v2 incremented with screeny & screenx respectively..\n");
    //printf("a) v1(%i)=v1(%i)+screeny(%i)\n", v1, v1-screeny, screeny);
    //printf("b) v2(%i)=v2(%i)+screenx(%i)\n", v2, v2-screenx, screenx);
	  
	//if (v1<0 || v2<0) { /*printf("2) v1 or v2 is less than 0 so end...\n");*/ return (word*)currentZone.v_16x16; }
        if (v1<0 || v2<0) { /*printf("2) v1 or v2 is less than 0 so end...\n");*/ return (word*)v_16x16; }

	unsigned short d3 = (v1/2) & 0x380; //(scaled y value to nearest 256)/2
	d3=d3/8;                      //?
    v2=v2/8;                      //(scaled x value per tile);
    
    //printf("2) d3 is created as a value to represent y coordinate in terms of 256, v2 also scaled by 8 before it is used in step 3...\n");
    //printf("a) d3 = (((v1(%i)/2) & 0x380)/8) = %i..\n", v1, d3);
    //printf("b) v2(%i) = v2(%i)/8\n", v2, v2*8); 
	
	word vram=0;                  //?
    vram=v2;                      //vram=current tile at screen x
	vram=vram/32;                 //(vram=(current tile at screen x)/32=current 256x256 at screen location(index)
	
    //printf("3) vram is created as a value to represent x coordinate in terms of 256, using v2 as a partial calculation..\n");
    //printf("a) vram(%i)=v2(%i)/32\n", vram,v2);
    
    //printf("4) d3 is used as the upper half and vram is used as the lower half in calculating the address in level layout corresponding to the 256x256 tile at screenx and screeny..\n");
    
    word yoff=0;                  //?
	yoff=d3;                      //?
	yoff=yoff/16;                 //?
	
    //printf("only a secondary value, yoff, is created and scaled(by zone width) to account for the y offset in layout index, and added to vram to then yield the total offset..\n");
    //printf("a) yoff(%i)=d3(%i)/16\n", yoff, d3);
   
    //yoff=yoff*(currentZone.width[layoutIndex/0x40]);  //?
    yoff = yoff * 128;


    //printf("b) yoff(%i)=(%i)yoff*(%i)currentZone.width[layoutIndex/0x40]\n", yoff, yoff/currentZone.width[layoutIndex/0x40], currentZone.width[layoutIndex/0x40]);
    
    vram=vram & 0x7F;             //(no bigger than 128)
	vram=(vram+(yoff));                 //compensate for the y val too
    
    //printf("c) vram(%i)=vram+(%i)yoff\n", vram, yoff); 
	//v2=vram;
	
    #ifdef debug_tiles
    //for (int ylp=0; ylp<currentZone.height; ylp++)
     //{
       // for (int xlp=0; xlp<currentZone.width; xlp++)
        //{
         //  //printf("%02X ", currentZone.v_lvllayout[xlp+(ylp*currentZone.width)]);
          // //printf("%02X ", xlp+(ylp*currentZone.width));
        //}
        ////printf("\n");
    //}
    #endif
     
    //word temp256=currentZone.v_lvllayout[vram+((layoutIndex)*8)];
    word temp256 = v_lvllayout[vram+((layoutIndex)*8)];

    word cur256=temp256;       //cur256=current level 256x256 at screen location calculated in vram
	//printf("5) vram is then used as the index in array for level layout to grab the 256x256 id\n");
	//printf("a) temp256(%i)=currentZone.v_lvllayout[vram(%i)+((layoutIndex=%i)*8)]\n", temp256, vram, layoutIndex);
	
    #ifdef debug_tiles
    if (old256!=temp256){/*printf("Drawing block at %i in v_lvllayout: %i \n", vram, cur256)*/}
    #endif
    
    old256=temp256;
    if (temp256 == 0) { /*printf("6) temp256==0, no 256 here...\n"); return (word*)currentZone.v_16x16; */}
    
	//printf("6) cur256>0, this is a valid 256 index so subtract 1 to account for the offset caused by 256 id 0\n");
	cur256=cur256-1; 
	cur256=cur256 & 0x007F;//this index value is never greater than 127
	//printf("a) cur256(%i)=cur256(%i)-1 \n", cur256, cur256+1);
	
    //then this index value is used and then modified to yield the proper index into 16x16 mappings for this 256
    
    //printf("7) this index value, cur256, is used as the upper half in a pre-calculation for the offset into 256x256 mappings for this 256 id)\n");
    //cur256=(cur256 << 8);        //this is9 in rom, or a rotr 7
    cur256=(cur256<<9);//+(cur256>>7);
    //printf("a) cur256(%i)=(cur256(%i)<<9)\n", cur256, cur256>>9);
    
    #ifdef debug_tiles
    //printf("cur256: %i\n", cur256);
    #endif
    
	//v1=used as offset index value into different mappings arrays based on screen y  (currently per pixel, has yet to be scaled)
    //v2=used as offset index value into different mappings arrays based on screen x  (currently per tile)
	//v1=v1/16;
	
	//printf("8) lower half of this calculation then accounts for the offset into the 256x256 mapping based on screen y & screen x)\n");
    //printf("considering the size of 1 256x256 entry (which points to a 16x16 so --2 BYTES--) the format is then...\n");
    //printf("0000000YYYYXXXX0 where the first bit is skipped for we are talking multiples of 2, or size of the entry...\n");
    
    //printf("a) v1(%i)=v1(%i)*2\n", v1*2, v1);
    v1=v1*2;      //extra bit to left, current 16x16 at y location translates to twice thesize for wordsize of 16x16
    #ifdef debug_tiles
    //printf("v1: %i\n", v1);
	//printf("v2: %i\n", v2);
	#endif
	
    v1=v1&0x1E0;  //0000000111100000       v1 scaled and now yields (tile offset [0,Y]): (0<=Y<16) where Y is current 16x16 tile offset into 256 based on screen y
	v2=v2&0x1E;   //0000000000011110       v2 scaled and now yields (tile offset [X,0]): (0<=X<16) where X is current 16x16 tile offset into 256 based on screen x    
	printf("b) v1(%i)=v1&0x1E0\n", v1);
	printbits(v1);
	printf("\n");
	printf("c) v2(%i)=v2&0x1E\n", v2);
	printbits(v2);
	printf("\n");
	
	unsigned short cur16index;
	
	//printf("9) finally, cur16index is created and used to hold the calculation for the offset into 16x16 tiles referred to by the current 256 and accounting for screen offset multiples of 16\n");
	
	cur16index=cur256+v1+v2+1;  //256TILEYYYYXXXX0 //two offsets are added along with the index value RELATIVE ADDRESS 0F CURRENT 16X16 MAPPING IN CORRESPONDING 256
    printf("a) cur16index(%i)=cur256(%i)+v1(%i)+v2(%i)+1     - note the additional 1 also accounts for the offset caused by 16x16 id 0\n",cur16index,cur256,v1,v2);	
    printbits(cur16index);
    
   //cur16index=cur16index/2;      //compensate for the word
	
	//long a0=d3;                   //RELATIVE ADDRESS 0F CURRENT 16X16 MAPPING IN CORRESPONDING 256
	//d3=*(a0);                      //we can grab value like this for 256x256 mappings reside at $0000 in RAM, therefore to calculate the relative address NOTHING is added
	//d3=(d3);
	#ifdef debug_tiles
    //printf("cur16index: %i\n", cur16index);
    #endif
                        
   //this is pc side
	unsigned short cur16;


    //unsigned short temp=((currentZone.v_256x256[cur16index]))+(currentZone.v_256x256[cur16index-1]<<8); 
    unsigned short temp=((v_256x256[cur16index]))+(v_256x256[cur16index-1]<<8);
    cur16=temp & 0x3FF;
    
    //printf("10) then cur16index is used as the offset into the main 256x256s array at which to grab the entry for 16x16 tile..\n");
    //printf("a) temp(%i) = ((currentZone.v2_256x256[(%i)cur16index]))+(currentZone.v_256x256[(%i)cur16index+1]<<8)\n", temp, cur16index, cur16index+1);
    
    //printf("11) the data for this entry is parsed into its individual parts..\n");
    
    //if (cur16>0x1FF){cur16=0;}
    flipx=((temp & 0x800)>>11);      //these are calculated elsewhere in therom
	flipy=((temp & 0x1000)>>12);
	//printf("a) cur16(%i) = temp & 0x3FF\n", cur16);
    //printf("b) flipx(%i) = ((temp & 0x800)>>11)\n", flipx);
	//printf("c) flipy(%i) = ((temp & 0x1000)>>12)\n", flipy);
	
	#ifdef debug_tiles
    //printf("cur16: %i\n", cur16);
    #endif
    //cur16=cur16&0xFFFF;                     //
    
	//cur16=cur16&0x03FF;                     //d3=index in 16x16s referred to
	cur16=cur16*8;                         //size of 1 16x16mapping
	//printf("12) the 16x16 tile id is then scaled by size of entry (8 bytes) to yield the proper offset into 16x16 tiles\n");  
    //printf("a) cur16(%i)=cur16(%i)*8\n", cur16, cur16/8);
	
	//a1=a1+cur16;                           //16x16 position added to relative offset
	//word *a1=(word*)&currentZone.v_16x16[cur16];
        word *a1=(word*)&v_16x16[cur16];

    ////printf("currentZone.v_16x16=%i\n", currentZone.v_16x16);
	
    #ifdef debug_tiles
    //printf("a1:%08X\n",a1);
    #endif
    
    //printf("13) a1 is calculated and returned to the code that called DrawBlocks to handle drawing this 16x16\n");
    //printf("a) word *a1(%08X)=(word*)&currentZone.v_16x16[cur16(%i)]\n",a1,cur16); 
    //printf("b) return a1;\n");
    return a1;

}

byte ArtUnc_MenuText[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x00,0x06,0x60,0x06,
0x60,0x66,0x60,0x66,0x60,0x66,0x66,0x06,0x60,0x66,0x00,0x66,0x00,0x06,0x66,
0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x66,0x00,0x00,
0x60,0x66,0x00,0x00,0x00,0x66,0x00,0x00,0x06,0x60,0x00,0x00,0x06,0x60,0x00,
0x06,0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x60,
0x00,0x06,0x00,0x66,0x00,0x00,0x00,0x66,0x00,0x00,0x06,0x60,0x00,0x00,0x66,
0x00,0x00,0x06,0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,
0x66,0x66,0x00,0x00,0x00,0x66,0x00,0x00,0x06,0x60,0x00,0x00,0x00,0x66,0x00,
0x06,0x00,0x66,0x00,0x06,0x66,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x06,0x66,0x00,0x00,0x60,0x66,0x00,0x06,0x00,0x60,0x00,0x66,0x66,
0x66,0x60,0x00,0x06,0x60,0x00,0x00,0x66,0x60,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x66,0x66,0x00,0x00,0x60,0x00,0x00,0x00,0x66,0x66,0x00,
0x00,0x00,0x06,0x60,0x06,0x00,0x66,0x60,0x00,0x66,0x66,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x66,0x00,0x00,0x66,0x00,0x00,0x06,0x66,
0x60,0x00,0x66,0x00,0x66,0x00,0x66,0x00,0x66,0x00,0x66,0x66,0x60,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x66,0x66,0x00,0x06,0x00,0x66,0x00,
0x00,0x06,0x60,0x00,0x00,0x66,0x00,0x00,0x06,0x60,0x00,0x00,0x66,0x60,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x00,0x06,0x60,
0x06,0x60,0x00,0x66,0x66,0x00,0x06,0x66,0x60,0x00,0x66,0x00,0x66,0x00,0x06,
0x66,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x00,
0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x00,0x66,0x66,0x00,0x00,0x00,0x66,
0x00,0x06,0x66,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x66,
0x66,0x00,0x06,0x06,0x00,0x00,0x00,0x66,0x60,0x00,0x00,0x06,0x06,0x00,0x06,
0x66,0x60,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x66,0x66,0x60,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x66,0x66,0x60,0x00,0x00,0x00,0x00,0x06,
0x66,0x66,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x60,0x00,0x00,0x00,0x66,0x00,0x06,0x66,0x66,0x60,0x06,0x66,0x66,
0x60,0x00,0x00,0x66,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x66,0x00,0x06,0x66,0x66,0x60,0x06,
0x66,0x66,0x60,0x00,0x00,0x66,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x60,0x06,0x60,0x06,0x60,0x06,
0x60,0x00,0x60,0x66,0x00,0x00,0x66,0x60,0x00,0x06,0x66,0x00,0x00,0x66,0x60,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x66,0x66,0x60,0x00,
0x00,0x66,0x00,0x00,0x06,0x60,0x00,0x00,0x66,0x00,0x00,0x06,0x60,0x00,0x00,
0x66,0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,
0x60,0x00,0x06,0x06,0x60,0x00,0x60,0x06,0x60,0x00,0x66,0x66,0x60,0x06,0x60,
0x06,0x60,0x66,0x00,0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x66,0x66,0x00,0x00,0x60,0x06,0x60,0x06,0x66,0x66,0x00,0x06,0x66,0x60,0x00,
0x66,0x00,0x66,0x00,0x66,0x66,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x66,0x66,0x00,0x06,0x60,0x06,0x60,0x06,0x60,0x00,0x00,0x66,0x00,
0x00,0x00,0x66,0x00,0x66,0x00,0x66,0x66,0x60,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x66,0x66,0x00,0x00,0x66,0x06,0x60,0x06,0x60,0x06,0x60,
0x06,0x60,0x06,0x60,0x66,0x00,0x66,0x00,0x66,0x66,0x60,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x60,0x00,0x66,0x00,0x00,0x06,0x60,
0x00,0x00,0x06,0x66,0x60,0x00,0x66,0x00,0x00,0x00,0x66,0x66,0x66,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x60,0x06,0x66,0x00,0x00,
0x06,0x60,0x00,0x00,0x06,0x66,0x66,0x00,0x66,0x60,0x00,0x00,0x66,0x60,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x00,0x06,0x66,
0x00,0x60,0x06,0x60,0x00,0x00,0x66,0x00,0x66,0x60,0x66,0x00,0x66,0x00,0x66,
0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x00,0x60,
0x00,0x66,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x66,0x66,0x00,0x66,0x00,0x66,
0x00,0x66,0x00,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,
0x60,0x00,0x00,0x06,0x60,0x00,0x00,0x66,0x00,0x00,0x00,0x66,0x00,0x00,0x06,
0x60,0x00,0x00,0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x06,0x60,0x00,0x00,0x06,0x60,0x06,0x00,0x66,0x00,0x66,0x00,0x66,
0x00,0x66,0x66,0x60,0x00,0x06,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x66,0x00,0x60,0x00,0x66,0x06,0x60,0x06,0x60,0x66,0x00,0x06,
0x66,0x60,0x00,0x66,0x00,0x66,0x00,0x66,0x00,0x06,0x60,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x06,0x60,0x00,0x00,0x66,0x00,0x00,0x06,0x60,0x00,
0x00,0x06,0x60,0x00,0x00,0x66,0x00,0x00,0x00,0x66,0x66,0x66,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x00,0x60,0x00,0x66,0x06,0x60,0x00,
0x66,0x66,0x60,0x06,0x06,0x06,0x60,0x06,0x00,0x06,0x60,0x66,0x00,0x06,0x60,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x00,0x60,0x00,0x66,0x00,
0x60,0x00,0x66,0x60,0x60,0x06,0x06,0x66,0x00,0x06,0x00,0x66,0x00,0x66,0x00,
0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x00,0x06,
0x60,0x06,0x60,0x66,0x60,0x66,0x60,0x66,0x60,0x66,0x60,0x66,0x00,0x66,0x00,
0x06,0x66,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x66,
0x00,0x00,0x66,0x00,0x60,0x06,0x60,0x06,0x60,0x06,0x66,0x66,0x00,0x66,0x60,
0x00,0x00,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x66,0x66,0x00,0x06,0x60,0x06,0x60,0x66,0x00,0x06,0x60,0x66,0x66,0x66,0x60,
0x66,0x00,0x66,0x00,0x66,0x66,0x66,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x66,0x66,0x00,0x00,0x66,0x00,0x60,0x06,0x60,0x06,0x60,0x06,0x66,
0x66,0x00,0x66,0x00,0x66,0x00,0x66,0x00,0x66,0x60,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x66,0x66,0x60,0x06,0x60,0x06,0x60,0x06,0x66,0x00,0x00,
0x00,0x66,0x66,0x00,0x66,0x00,0x66,0x60,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x06,0x66,0x66,0x60,0x00,0x06,0x60,0x00,0x00,0x06,
0x60,0x00,0x00,0x66,0x00,0x00,0x00,0x66,0x00,0x00,0x00,0x66,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x00,0x60,0x00,0x66,0x00,0x60,
0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x00,0x66,0x66,0x66,0x00,0x66,0x66,0x60,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x60,0x00,0x60,0x06,0x60,
0x00,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x66,0x00,0x06,0x66,0x60,0x00,0x66,
0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x00,0x00,0x60,
0x66,0x00,0x00,0x60,0x66,0x06,0x06,0x60,0x66,0x66,0x66,0x00,0x66,0x00,0x66,
0x00,0x66,0x00,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x60,
0x00,0x60,0x06,0x66,0x06,0x00,0x00,0x66,0x60,0x00,0x00,0x06,0x60,0x00,0x00,
0x66,0x66,0x00,0x66,0x00,0x66,0x60
};


//ShowErrorMessage:
void DrawText(char* text, int len, int x, int y)
{
     
        char *gentext=PCtoSonicText(text,len);
        
		//lea	(vdp_data_port).l,a6
		//locVRAM	$F800
	    word *vRambuf=getvRam();
	        
    	//lea	(Art_Text).l,a0
		for (int d1=0x27F, index=0; d1>0; d1--, index++)
        {
            //move.w	#$27F,d1
            //@loadgfx:
            //move.w	(a0)+,(a6)	        
            vRambuf[index+(0xF800/2)]=((ArtUnc_MenuText[index*2]<<8)&0xFF00)+((ArtUnc_MenuText[(index*2)+1])&0x00FF);
        }//dbf	d1,@loadgfx

		//WHERE DRAWTEXT WILL DIFFER FROM THE ORIGINAL ERROR TEXT ROUTINE DIFFERS HERE...
        //moveq	#0,d0		; clear	d0
		//move.b	(v_errortype).w,d0 ; load error code
		//move.w	ErrorText(pc,d0.w),d0
		//lea	ErrorText(pc,d0.w),a0
		//--------------
		//WE WANT TO PLACE THE TEXT IN VRAM
        
        //***locVRAM	(vram_fg+$604)
		//word *fgRambuf=getfgRam();
		
        //moveq	#$12,d1		; number of characters (minus 1)  (D1 HERE IS LENGTH, len CAN BE THE LENGTH AS AN ADDITIONAL ARGUMENT..)

		for (int count=0;len>0; len--,count++)
		{
	    //@showchars:
		//moveq	#0,d0
		//move.b	(a0)+,d0     A0 now refers to the text, source will be the string in our case
		//addi.w	#$790,d0
		//***move.w	d0,(a6)
            //printf("gentext[count]=%i\n", gentext[count]);
            //fgRambuf[(y*64)+x+count]=gentext[count]+0x2000+0x790;//(0x790;   //
            word tileval=(((byte)(gentext[count]))+0x7C0)^0x2000;
            //tileval=((tileval&0x00FF)<<8)+((tileval&0xFF00)>>8);
            DrawTileFG(0,0,(y*64)+x+count,tileval);
        }//dbf	d1,@showchars	; repeat for number of characters
		//rts
}	

char *PCtoSonicText(char *pcText, int len)
{
     
     for (int lp=0; lp<len; lp++)
     {
         byte charVal=pcText[lp];  //art starts at 48th ASCII index, '0'    
         byte newVal;
         if (charVal==32) { newVal=42; }
         else if (charVal==36) { newVal=10; }  // '$' dollar sign is 10th index
         else if (charVal==45) { newVal=11; }  // '-' minus sign is 11th index
         else if (charVal>=48 && charVal <= 57) 
                 newVal=charVal-48;    
         else if (charVal==61) { newVal=12; }  // '=' equals is 12th index
         //todo: implement two arrow type characters
         else if ((charVal>=65) && (charVal<=88)) //'uppercase alphabet A-X' 
            newVal=(charVal-65)+17;       // 'A-X index
         else if ((charVal==89 || charVal==90)) //'uppercase alpha A-Z'
            newVal=(charVal-89)+15;
         else if ((charVal>=97) && (charVal<=120)) //'uppercase alphabet A-X' 
            newVal=(charVal-97)+17;       // 'A-X index
         else if ((charVal==121 || charVal==122)) //'uppercase alpha A-Z'
            newVal=(charVal-121)+15;
         else
            newVal=42;
         newText[lp]=newVal;
     }
     
     return newText;
}
     
